package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.config.ObjectUtil;
import com.heima.common.constants.WmNewsMessageConstants;
import com.heima.common.dtos.PageResponseResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.model.common.UpDownMsg;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.util.WmThreadLocalUtil;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Resource
    private WmMaterialMapper wmMaterialMapper;
    @Resource
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Resource
    private WmNewsAutoScanService wmNewsAutoScanService;
    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    @Override
    public ResponseResult<List<WmNews>> findAll(WmNewsPageReqDto dto) {
        //根据条件进行分页查询

        //1.分页
        IPage<WmNews> page = new Page<>(dto.getPage(), dto.getSize());

        //2.进行条件查询
        IPage<WmNews> paged = this.lambdaQuery()
                .like(dto.getKeyword() != null, WmNews::getTitle, dto.getKeyword())//根据关键字查询
                .eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus())//根据状态查询
                .eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId())//根据频道id查询
                .gt(dto.getBeginPubDate() != null, WmNews::getSubmitedTime, dto.getBeginPubDate())//大于开始时间的文章
                .lt(dto.getEndPubDate() != null, WmNews::getSubmitedTime, dto.getEndPubDate())//小于结束时间的文章
                .page(page);//分页
        //3.构建返回实例
        return PageResponseResult.<List<WmNews>>builder()
                .currentPage(Convert.toInt(paged.getPages()))
                .size(Convert.toInt(paged.getSize()))
                .total(Convert.toInt(paged.getTotal()))
                .data(paged.getRecords())
                .build();
    }

    @Override
    @Async
    public ResponseResult<Object> submitNews(WmNewsDto dto) {
        //0.条件查询
        if (ObjectUtil.isEmpty(dto.getContent())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //1.保存或者修改数据
        WmNews wmNews = null;
        //判断是新增还是修改操作
        if (ObjectUtil.isEmpty(dto.getId())) {
            //进行新增操作
            wmNews = this.operatorNews(dto);
            this.save(wmNews);
            //进行新增操作
        }

        //不为空，通过id进行删除关联表
        //修改操作,先删除关系表的数据
        this.wmNewsMaterialMapper.deleteRelations(dto.getId());
        wmNews = this.operatorNews(dto);
        this.updateById(wmNews);

        //判断是否为草稿
        if (ObjectUtil.equal(dto.getStatus(), 0)) {
            //不进行操作
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        //不为草稿进行关系表的添加操作

        //2.进行素材关联表数据的插入
        //获得标题图片的数据
        List<String> mainList = dto.getImages();
        ArrayList<Integer> mainMaterials = this.getMaterialUrlIds(mainList);
        this.wmNewsMaterialMapper.saveRelations(mainMaterials, dto.getId(), Convert.toShort(1));

        //图片处理
        List<String> contentList = new ArrayList<>();
        //将内容中的素材放入集合中
        JSONArray jsonArray = JSONUtil.parseArray(dto.getContent());
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String value = jsonObject.getStr("value");
            contentList.add(value);
        }
        ArrayList<Integer> contentMaterials = this.getMaterialUrlIds(contentList);
        this.wmNewsMaterialMapper.saveRelations(contentMaterials, dto.getId(), Convert.toShort(0));
        //处理完，进行远程调用fegin中的接口进行文章数据的审核
        wmNewsAutoScanService.autoScanWmNews(wmNews.getId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //通过素材内容查询素材id
    private ArrayList<Integer> getMaterialUrlIds(List<String> list) {
        ArrayList<Integer> materialUrlIds = new ArrayList<>();
        for (String string : list) {
            Integer materialUrlId = wmMaterialMapper.selectIdByMaterialUrl(string);
            materialUrlIds.add(materialUrlId);
        }
        return materialUrlIds;
    }

    //新增news
    private WmNews operatorNews(WmNewsDto dto) {
        //新增操作
        WmNews wmNews = BeanUtil.toBean(dto, WmNews.class);
        // 1. 判断是几图模式,
        if (ObjectUtil.equal(dto.getType(), 1)) {
            //1图，image不需要拼接
            wmNews.setImages(CollUtil.getFirst(dto.getImages()));
        }
        if (ObjectUtil.equal(dto.getType(), 3)) {
            //需要拼接
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < dto.getImages().size(); i++) {
                if (i == dto.getImages().size() - 1) {
                    stringBuilder.append(dto.getImages().get(i));
                } else {
                    stringBuilder.append(dto.getImages().get(i)).append(",");
                }
            }
            wmNews.setImages(stringBuilder.toString());
        }
        //自动时也使用1图模式，选取第一个
        if (ObjectUtil.equal(dto.getType(), -1)) {
            //先判断有没有图
            if (ObjectUtil.isNotEmpty(dto.getImages())) {
                //有图，选取第一个为主图
                wmNews.setImages(CollUtil.getFirst(dto.getImages()));
            }
            //没有图则不进行操作

        }

        //其他数据补充
        wmNews.setUserId(Convert.toInt(WmThreadLocalUtil.getUserId()));
        wmNews.setCreatedTime(new Date());

        return wmNews;
    }


    @Override
    public ResponseResult<WmNews> queryNewsById(Integer id) {
        WmNews news = null;
        try {
            news = this.getById(id);
        } catch (Exception e) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        return ResponseResult.okResult(news);
    }

    @Override
    public ResponseResult<AppHttpCodeEnum> deleteNewsById(Integer id) {
        if (ObjectUtil.isEmpty(id)) {
            return ResponseResult.errorResult(501, "文章id不可缺少");
        }
        WmNews wmNews = this.getById(id);
        if (ObjectUtil.isEmpty(wmNews)) {
            return ResponseResult.errorResult(1002, "文章不存在");
        }
        if (ObjectUtil.equal(wmNews.getStatus(), 1)) {
            return ResponseResult.errorResult(501, "文章已发表，不能删除");
        }

        try {
            //移除操作
            this.removeById(id);
        } catch (Exception e) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult<AppHttpCodeEnum> downOrUp(WmNewsDto wmNewsDto) {
        //获得文章id
        Integer newsId = wmNewsDto.getId();
        if (ObjectUtil.isEmpty(newsId)) {
            return ResponseResult.errorResult(501, "文章id不可缺少");
        }
        WmNews wmNews = this.getById(newsId);
        if (ObjectUtil.isEmpty(wmNews)) {
            return ResponseResult.errorResult(1002, "文章不存在");
        }
        if (!ObjectUtil.equal(wmNews.getStatus(), WmNews.Status.PUBLISHED.getCode())) {
            return ResponseResult.errorResult(501, "当前文章不是发布状态，不能上下架");
        }
        try {
            //进行改变上架状态操作
            if (!ObjectUtil.equalsAny(wmNews.getEnable(), (short) 0, (short) 1)) {
                return ResponseResult.errorResult(501, "文章的状态只能为0或者1");
            }
            wmNews.setEnable(wmNewsDto.getEnable());
            this.updateById(wmNews);

            //kafaka
            if (ObjectUtil.isNotEmpty(wmNews.getArticleId())) {
                //构建发送的数据
                String msg = UpDownMsg.builder().enable(wmNews.getEnable()).articleId(wmNews.getArticleId()).build().toJson();
                //通知kafaka，发送消息给它，让文章进行监听
                this.kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC, msg);
            }
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        } catch (Exception e) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
    }
}
